﻿// TestSilverlightApp.MainPage.xaml.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       MainPage.xaml.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/05/2010
// ----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
using System.Windows;
using System.Windows.Controls;
using HSS.ServiceModel;
using HSS.ServiceModel.Internal;
using TestSharedData;
using TestVirtualService;

namespace TestSilverlightApp
{
	public partial class MainPage : UserControl
	{
		ObservableCollection<Stats> statistics = new ObservableCollection<Stats>();

		sealed class TestServiceConfig : IChannelConfiguration
		{
			public string ServicePath
			{
				get { return "services"; }
			}

			public string ServiceTypeName
			{
				get { return "TestVirtualService.TestService"; }
			}

			public string ServiceToken
			{
				get { return "chuck"; }
			}

			public static IChannelConfiguration Instance
			{
				get
				{
					return new TestServiceConfig();
				}
			}
		}

		public MainPage()
		{
			InitializeComponent();

			VirtualChannel<ITestService>.Initialize(TestServiceConfig.Instance);

			this.dataGrid1.ItemsSource = statistics;
			statistics.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(statistics_CollectionChanged);
		}

		void statistics_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			var average = (from s in statistics
						   select s.Elapsed).Sum();
			if (average < 1)
				average = 0;
			else if (statistics.Count < 2)
				average = 0;
			else
				average = average / statistics.Count;
			average = Math.Round(average, 0);
			this.txtAverage.Text = average.ToString();
		}

		void Test1()
		{
			var operation = "DoSomeWork";
			//var vop = new VirtualActionOperation<ITestService>(testServiceConfig, TimeoutSettings.Default(10));
			//var watcher1 = Stopwatch.StartNew();
			//vop.InvokeAsync(operation, (error) =>
			//    {
			//        watcher1.Stop();
			//        var d1 = watcher1.Elapsed.TotalMilliseconds;
			//        watcher1 = null;

			//        statistics.Add(new Stats()
			//            {
			//                Elapsed = d1,
			//                MethodName = operation,
			//                Timestamp = DateTime.Now
			//            });

			//        if (null != error)
			//            MessageBox.Show(error.Message);

			//    });
			var watcher1 = Stopwatch.StartNew();
			VirtualChannel<ITestService>.Invoke(s => s.DoSomeWork(), (error) =>
				{
					watcher1.Stop();
					var d1 = watcher1.Elapsed.TotalMilliseconds;
					watcher1 = null;

					statistics.Add(new Stats()
						{
							Elapsed = d1,
							MethodName = operation,
							Timestamp = DateTime.Now
						});

					if (null != error)
						MessageBox.Show(error.Message);
				});


			//string operation = "GetPeople";
			//Stopwatch watcher1 = Stopwatch.StartNew();
			//VirtualChannel<ITestService>.InvokeFuncAsync<IEnumerable<Person>, string>(operation, (result, error, state) =>
			//{
			//    watcher1.Stop();
			//    double d1 = watcher1.Elapsed.TotalMilliseconds;
			//    watcher1 = null;

			//    if (null != error)
			//    {
			//        MessageBox.Show(error.ToString());
			//        return;
			//    }

			//    statistics.Add(new Stats()
			//        {
			//            Elapsed = d1,
			//            MethodName = state,
			//            Timestamp = DateTime.Now
			//        });

			//}, operation);
		}
		void Test2()
		{
			var op = "MoreWork";
			var sw = Stopwatch.StartNew();
			VirtualChannel<ITestService>.Invoke(s => s.MoreWork("Chuck"), (result, error) =>
			{
				sw.Stop();
				var totalMS = sw.Elapsed.TotalMilliseconds;
				sw = null;

				if (null != error)
				{
					MessageBox.Show(error.Message);
					return;
				}

				statistics.Add(new Stats()
				{
					Elapsed = totalMS,
					MethodName = op,
					Timestamp = DateTime.Now
				});
			});
		}

		private void Button_Click(object sender, RoutedEventArgs e)
		{
			Test1();
		}

		private void btnLogin_Click(object sender, RoutedEventArgs e)
		{
			System.Windows.Browser.HtmlPage.Window.Navigate(new Uri("account/login.aspx", UriKind.Relative));
		}

		private void btnLogout_Click(object sender, RoutedEventArgs e)
		{
			System.Windows.Browser.HtmlPage.Window.Navigate(new Uri("default.aspx", UriKind.Relative));
		}

		private void btnTestAuthMethod_Click(object sender, RoutedEventArgs e)
		{
			Test2();
		}

		private void btnClearGrid_Click(object sender, RoutedEventArgs e)
		{
			this.statistics.Clear();
		}
	}

	#region Stats
	public class Stats : INotifyPropertyChanged
	{

		public Stats()
		{

		}

		/// <summary>
		/// Gets or sets the MethodName value.
		/// </summary>
		public string MethodName
		{
			get { return this._methodName; }
			set
			{
				if (this._methodName != value)
				{
					this._methodName = value;
					this.OnPropertyChanged("MethodName");
				}
			}
		} string _methodName;

		/// <summary>
		/// Gets or sets the Elapsed value.
		/// </summary>
		public double Elapsed
		{
			get { return this._elapsed; }
			set
			{
				if (this._elapsed != value)
				{
					this._elapsed = value;
					this.OnPropertyChanged("Elapsed");
				}
			}
		} double _elapsed;

		/// <summary>
		/// Gets or sets the Timestamp value.
		/// </summary>
		public DateTime Timestamp
		{
			get { return this._timestamp; }
			set
			{
				if (this._timestamp != value)
				{
					this._timestamp = value;
					this.OnPropertyChanged("Timestamp");
				}
			}
		} DateTime _timestamp;


		public event PropertyChangedEventHandler PropertyChanged;

		void OnPropertyChanged(string propertyName)
		{
			var handler = PropertyChanged;
			if (null != handler)
				handler(null, new PropertyChangedEventArgs(propertyName));
		}
	}
	#endregion

	#region Stopwatch
	/// <summary>
	/// Stopwatch is used to measure the general performance of Silverlight 
	/// functionality. The resolution of this timer is limited to <see cref="Environment.TickCount"/>.
	/// </summary>
	public sealed class Stopwatch
	{
		#region Fields
		private int startTickCount = 0;
		private int endTickCount = 0;
		#endregion

		#region Constructors
		/// <summary>
		/// Creates an instance of the Stopwatch class.
		/// </summary>
		public Stopwatch()
		{
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets a value indicating whether the instance is currently recording.
		/// </summary>
		public bool IsRunning { get; private set; }
		/// <summary>
		/// Gets the Elapsed time as the total number of milliseconds.
		/// </summary>
		public long ElapsedMilliseconds
		{
			get
			{
				return this.ElapsedTicks / TimeSpan.TicksPerMillisecond;
			}
		}
		/// <summary>
		/// Gets the number of ticks.
		/// </summary>
		public long ElapsedTicks
		{
			get
			{
				return this.Elapsed.Ticks;
			}
		}
		/// <summary>
		/// Gets the Elapsed time as a Timespan.
		/// </summary>
		public TimeSpan Elapsed
		{
			get
			{
				if (startTickCount == 0)
					return TimeSpan.Zero;
				if (endTickCount == 0)
					return TimeSpan.FromMilliseconds(Environment.TickCount - startTickCount);
				return TimeSpan.FromMilliseconds(endTickCount - startTickCount);
			}
		}
		#endregion

		#region Methods

		/// <summary>
		/// Creates a new instance of the class and starts the watch immediately.
		/// </summary>
		/// <returns>An instance of Stopwatch, running.</returns>
		public static Stopwatch StartNew()
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			return sw;
		}

		/// <summary>
		/// Completely resets and deactivates the timer.
		/// </summary>
		public void Reset()
		{
			startTickCount = 0;
			endTickCount = 0;
			IsRunning = false;
		}
		/// <summary>
		/// Begins the timer.
		/// </summary>
		public void Start()
		{
			if (this.IsRunning)
				return;

			if (this.startTickCount > 0 && this.endTickCount > 0)
				this.startTickCount = this.startTickCount + (Environment.TickCount - this.endTickCount);
			else
				this.startTickCount = Environment.TickCount;

			this.IsRunning = true;
		}
		/// <summary>
		/// Stops the current timer.
		/// </summary>
		public void Stop()
		{
			if (this.IsRunning)
			{
				endTickCount = Environment.TickCount;
				this.IsRunning = false;
			}
		}
		#endregion
	}
	#endregion
}